#include <iostream>

#include <iostream>
#include <cerrno>
#include <cstring>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#include "Comm.hpp"

void Usage(std::string porcess)
{
    std::cout << "usage : \n\t" << porcess << " localip localport " << std::endl;
}

//   ./tcpclient 127.0.0.1 8888
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage(argv[0]);
        return Usage_Err;
    }

    std::string ip = argv[1];
    uint16_t port = std::atoi(argv[2]);

    // 1.创建文件细节
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        std::cout << "create socket error ,  errno :  " << errno << ", strerror : " << strerror(errno) << std::endl;
        return Socket_Err;
    }

    struct sockaddr_in local;
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_port = htons(port);

    // inet_addr(因为它是在同一个静态缓冲区中工作的，这样在多线程环境下可能会导致竞态条件和不确定的行为)
    // p(process 进程)  n(网络)
    inet_pton(AF_INET, ip.c_str(), &local.sin_addr); // 4字节ip, 网络序列

    // 2.连接服务器
    if (connect(sockfd, SOCKADDR_IN_TO_SOCKADDR(&local), sizeof(local)) < 0) // 发消息自动绑定
    {
        std::cout << "create socket error ,  errno :  " << errno << ", strerror : " << strerror(errno) << std::endl;
        return Connect_Err;
    }

    // 读取服务列表
    char service_list[1024];
    int n = read(sockfd, service_list, sizeof(service_list) - 1);
    if (n > 0)
    {
        service_list[n] = 0;
        std::cout << "服务列表 :  " << service_list << std::endl;
    }
    else if (n == 0)
    {
        std::cout << "Server shutdown" << std::endl;
        return 0;
    }
    else
    {
        std::cout << "create socket error ,  errno :  " << errno << ", strerror : " << strerror(errno) << std::endl;
        return 1;
    }

    // 选择服务
    std::cout << "请选择服务: ";
    std::string massage;
    std::getline(std::cin, massage);
    write(sockfd, massage.c_str(), massage.size());

    std::cout << "Please Enter$ ";
    std::getline(std::cin, massage);
    if (massage == "quit")
    {
        std::cout << "quit success !!!" << std::endl;
        return 1;
    }
    n = write(sockfd, massage.c_str(), massage.size());
    if (n > 0)
    {
        char buffer[1024];
        int m = read(sockfd, buffer, sizeof(buffer));
        if (m > 0)
        {
            buffer[m] = 0;
            std::cout << buffer << std::endl;
        }
        else
        {
            return 1;
        }
    }
    // // 并没有向server一样，产生新的sockfd.未来我们就用connect成功的sockfd进行通信即可
    // while (true)
    // {
    //     std::cout << "Please Enter$ ";
    //     std::string massage;
    //     std::getline(std::cin, massage);
    //     int n = write(sockfd, massage.c_str(), massage.size());
    //     if (n > 0)
    //     {
    //         char buffer[1024];
    //         int m = read(sockfd, buffer, sizeof(buffer));
    //         if (m > 0)
    //         {
    //             buffer[m] = 0;
    //             std::cout << buffer << std::endl;
    //         }
    //         else
    //         {
    //             break;
    //         }
    //     }
    //     else
    //     {
    //         break;
    //     }
    // }

    close(sockfd);
    return 0;
}
